<?php

namespace Platform\Libs;

use Aliyun\OSS\OSSClient;

include_once PLATFROM_LIB_PATH . 'aliyunOSS/OssClient.php';

/**
 * 阿里云OSS管理
 */
class AliOssManage {

    /**
     * 阿里云图片上传静态类
     * @var \OssClient
     */
    private static $OssClient = null;

    /**
     * 阿里云访问key_id
     */
    const ACCESS_KEY_ID = 'LTAI51B4U69qnEtQ';

    /**
     * 阿里云访问secret
     */
    const ACCESS_KEY_SECRET = 'gduuTkev5vHmEKPfouwUvLm4Cj96VF';

    /**
     * 上海阿里云OSS数据中心访问域名
     */
    const HOSTNAME = 'oss-cn-shanghai.aliyuncs.com';

    /**
     * 深圳阿里云OSS数据中心访问域名
     */
    const SHENZHEN_HOSTNAME = 'oss-cn-shenzhen.aliyuncs.com';

    /**
     * 杭州阿里云OSS数据中心访问域名
     */
    const HANGZHOU_HOSTNAME = 'oss-cn-hangzhou.aliyuncs.com';

    /**
     * 默认阿里云bucket
     */
    const DEFAULT_BUCKET = 'testimg-xuzhong';

    /**
     * 红包视频bucket
     */
    const REDPACKET_BUCKET = 'redpacket-video';

    /**
     * 默认上传路径(必须以’/‘结尾)
     */
    const DEFAULT_DIR = "/";

    /**
     * 默认签名过期时间
     */
    const DEFAULT_SIGN_EXPIRE_TIME = 120;

    /**
     * 广告文件夹
     */
    const AD_BANNER_DIR = "Ad/";

    /**
     * 视频文件夹
     */
    const REDPACKET_VIDEO_DIR = "mp4/";

    /**
     * 红包小程序二维码
     */
    const REDPACKET_ACODE_DIR = "acode/";

    /**
     * 管理后台图片文件夹
     */
    const ADMIN_IMG_DIR = "system/img/";

    /**
     * 素材图
     */
    const MATERIAL_IMG_DIR = "material/img/";

    /**
     * 素材视频
     */
    const MATERIAL_VIDEO_DIR = "mp4/material/video/";

    /**
     * 素材音频
     */
    const MATERIAL_MUSIC_DIR = "material/music/";

    public function __construct($accessKeyId, $accessKeySecret, $hostname) {
        $this->getOssClient($accessKeyId, $accessKeySecret, $hostname);
    }

    /**
     * 获取阿里云OssClient
     * @return \OssClient
     */
    public static function getOssClient($accessKeyId, $accessKeySecret, $hostname) {
        if (empty($accessKeyId)) {
            $accessKeyId = self::ACCESS_KEY_ID;
        }
        if (empty($accessKeySecret)) {
            $accessKeySecret = self::ACCESS_KEY_SECRET;
        }
        if (empty($hostname)) {
            $hostname = self::HOSTNAME;
        }
        if (!empty(self::$OssClient)) {
            return self::$OssClient;
        } else {
            $OssClient = new \OssClient($accessKeyId, $accessKeySecret, $hostname);
            self::$OssClient = $OssClient;
        }
        return self::$OssClient;
    }

    /**
     * 上传对象到阿里云
     * @param $object
     * @param $file
     * @param string $bucket
     * @return null
     * @throws \OssException
     */
    public function aliyunUpload($object, $file, $bucket = self::DEFAULT_BUCKET) {
        $response = self::$OssClient->uploadFile($bucket, $object, $file);
        return $response;
    }

    function gmt_iso8601($time) {
        $dtStr = date("c", $time);
        $mydatetime = new \DateTime($dtStr);
        $expiration = $mydatetime->format(\DateTime::ISO8601);
        $pos = strpos($expiration, '+');
        $expiration = substr($expiration, 0, $pos);
        return $expiration . "Z";
    }

    /**
     * 
     * @param string $dir   路径
     * @param type $expire  设置该policy超时时间是10s. 即这个policy过了这个有效时间，将不能访问
     * @param type $bucket  bucket地址
     * @param type $endpoint bucket的endpoint地址
     */
    public function getSign($dir = self::DEFAULT_DIR, $expire = self::DEFAULT_SIGN_EXPIRE_TIME, $bucket = self::DEFAULT_BUCKET, $endpoint = self::HOSTNAME) {
        $id = self::ACCESS_KEY_ID;
        $key = self::ACCESS_KEY_SECRET;
        $host = 'http://' . $bucket . "." . $endpoint; //bucket+endpoint
        $now = time();
//        $expire = 30; //
        $end = $now + $expire;
        $expiration = $this->gmt_iso8601($end);

        $dir = $dir . date('Y-m', time()) . "/"; //添加子目录,以时间名创建
        //最大文件大小.用户可以自己设置
        $condition = array(0 => 'content-length-range', 1 => 0, 2 => 2 * 1024 * 1024 * 1024); //单位b
        $conditions[] = $condition;

        //表示用户上传的数据,必须是以$dir开始, 不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录
        $start = array(0 => 'starts-with', 1 => '$key', 2 => $dir);
        $conditions[] = $start;


        $arr = array('expiration' => $expiration, 'conditions' => $conditions);
        //echo json_encode($arr);
        //return;
        $policy = json_encode($arr);
        $base64_policy = base64_encode($policy);
        $string_to_sign = $base64_policy;
        $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true));

        $response = array();
        $response['accessid'] = $id;
        $response['host'] = $host;
        $response['policy'] = $base64_policy;
        $response['signature'] = $signature;
        $response['expire'] = $end;
        //这个参数是设置用户上传指定的前缀
        $response['dir'] = $dir;
        return $response;
    }

    /**
     * 生成GetObject的签名url,主要用于私有权限下的读访问控制
     * @param string $object 阿里云上传相对路径的地址，原文件路径地址
     * @param int $timeout 超时时间
     * @param string $bucket 阿里云bucket名
     * @return bool|string
     */
    public function getSignedUrlForGettingObject($object, $timeout, $bucket = self::DEFAULT_BUCKET) {
        try {
            $signedUrl = self::$OssClient->signUrl($bucket, $object, $timeout);
        } catch (\OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return false;
        }
        return $signedUrl;
    }

    /**
     * 删除object
     *
     * @param OssClient $ossClient OSSClient实例
     * @param string $bucket bucket名字
     * @return null
     */
    function deleteObject($bucket = self::DEFAULT_BUCKET, $object) {
        $OssClient = self::$OssClient;
        try {
            if ($OssClient->doesObjectExist($bucket, $object)) {
                $OssClient->deleteObject($bucket, $object);
            }
        } catch (OssException $e) {

            return false;
        }
        return true;
    }

    /**
     * 删除object数组
     *
     * @param OssClient $ossClient OSSClient实例
     * @param string $bucket bucket名字
     * @return null
     */
    function deleteObjects($bucket = self::DEFAULT_BUCKET, $object) {
        $OssClient = self::$OssClient;
        try {
            $OssClient->deleteObjects($bucket, $object);
        } catch (OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return false;
        }
        return true;
    }

    function putObject($object, $content, $bucket = self::DEFAULT_BUCKET, $options = NULL) {
        $OssClient = self::$OssClient;
        try {
            $response = $OssClient->putObject($bucket, $object, $content, $options);
        } catch (OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return false;
        }
        return true;
    }

}
